using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Alison.API
{
	public class Startup
	{
		public Startup(IConfiguration configuration) {
			Configuration = configuration;
		}

		public IConfiguration Configuration { get; }

		// This method gets called by the runtime. Use this method to add services to the container.
		public void ConfigureServices(IServiceCollection services) {
			 
			//自动注入
			AutoDI.AddDataService(services);
			services.AddControllersWithViews();
			services.AddOptions();
			services.AddControllers();

            #region 注册Swagger

            //添加Swagger
            services.AddSwaggerGen(c => {
				c.SwaggerDoc("v1", new OpenApiInfo {
					Version = "v1",
					Title = "Alison.API",
					Description = " 这个是一个测试的API接口文档 ASP.NET Core Web API For .NET 5",
					Contact = new OpenApiContact {
						Name = "爱老师",
						Email = "870951635@qq.com",
						Url = new Uri("https://www.baidu.com")
					},
					 License = new OpenApiLicense {
						  Name = "许可证：粤ICP 121454121",
						   Url = new Uri("https://www.baidu.com")
					 } 
				});

				//获取应用程序所在目录（绝对，不受工作目录影响，建议采用此方法获取路径）
				var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);
				var xmlPath = Path.Combine(basePath, "Alison.API.xml");
				c.IncludeXmlComments(xmlPath);
				c.EnableAnnotations();

				//Bearer 的scheme定义
				var securityScheme = new OpenApiSecurityScheme() {
					Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
					Name = "Authorization",
					//参数添加在头部
					In = ParameterLocation.Header,
					//使用Authorize头部
					Type = SecuritySchemeType.Http,
					//内容为以 bearer开头
					Scheme = "bearer",
					BearerFormat = "JWT"
				};

				//把所有方法配置为增加bearer头部信息
				var securityRequirement = new OpenApiSecurityRequirement
					{
						{
								new OpenApiSecurityScheme
								{
									Reference = new OpenApiReference
									{
										Type = ReferenceType.SecurityScheme,
										Id = "bearerAuth"
									}
								},
								new string[] {}
						}
					};

				//注册到swagger中
				c.AddSecurityDefinition("bearerAuth", securityScheme);
				c.AddSecurityRequirement(securityRequirement);
			});
			#endregion

			#region 配置JWT认证 
			// 1、先Nuget  Microsoft.AspNetCore.Authentication.JwtBearer
			// 2、注册Jwt 代码 
			services.Configure<TokenManagement>(Configuration.GetSection("tokenConfig"));
			var token = Configuration.GetSection("tokenConfig").Get<TokenManagement>();
			services.AddAuthentication(x =>
			{
				x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
				x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
			}).AddJwtBearer(x =>
			{
				x.RequireHttpsMetadata = false;
				x.SaveToken = true;
				//Token Validation Parameters
				x.TokenValidationParameters = new TokenValidationParameters
				{
					ValidateIssuerSigningKey = true,
					//获取或设置要使用的Microsoft.IdentityModel.Tokens.SecurityKey用于签名验证。
					IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.
					GetBytes(token.Secret)),
					//获取或设置一个System.String，它表示将使用的有效发行者检查代币的发行者。
					ValidIssuer = token.Issuer,
					//获取或设置一个字符串，该字符串表示将用于检查的有效受众反对令牌的观众。
					ValidAudience = token.Audience,
					ValidateIssuer = false,
					ValidateAudience = false,
				};
			});
			//注册Token验证接口，注册到StartUp

			#endregion
			 
		}

		// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
		public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
			
            //设置在开发环境才进入该界面，为了在部署在IIS环境中显示接口信息，应把if内的代码放出来
			/*
			if (env.IsDevelopment()) {
				app.UseDeveloperExceptionPage();
				app.UseSwagger();
				app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Alison.API v1"));
			}
			*/
			{    ////任何环境都可以进入
				app.UseDeveloperExceptionPage();
				app.UseSwagger();
				app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Alison.API v1"));
			}

			app.UseHttpsRedirection();

			app.UseRouting();

			app.UseAuthorization();

			app.UseEndpoints(endpoints => {
				endpoints.MapControllers();
			});
		}
	}
}
